from tkinter import Frame, W, Button
import time
from Detect import Detect
from PIL import ImageTk
from functools import partial


class LocatorGui(Frame):
	def __init__(self, parent, owner_frame, callback):
		super().__init__(owner_frame)
		self.parent = parent
		self.callback = callback
		self.detector = Detect()

		self.top_right = self._create_button(0, 0)
		self.top_left = self._create_button(0, 1)
		self.bottom_right = self._create_button(1, 0)
		self.bottom_left = self._create_button(1, 1)

	def start(self, key, index):
		self.key = key
		self.index = index
		self.parent.root.state('iconic')
		time.sleep(0.3)
		image = self.detector.capture()
		self.parent.root.state('normal')

		image_cut = ImageCut(image, (0, 0, image.size[0], image.size[1]))

		self._set_buttons_from_cut(image_cut)

		self.top_right.grid()
		self.top_left.grid()
		self.bottom_right.grid()
		self.bottom_left.grid()

	def _set_buttons_from_cut(self, image_cut):
		image_cut.cut()

		if image_cut.tr is None:
			self.top_right.grid_remove()
		else:
			image_cut.tr.set_button_image(self.top_right)

		if image_cut.tl is None:
			self.top_left.grid_remove()
		else:
			image_cut.tl.set_button_image(self.top_left)

		if image_cut.br is None:
			self.bottom_right.grid_remove()
		else:
			image_cut.br.set_button_image(self.bottom_right)

		if image_cut.bl is None:
			self.bottom_left.grid_remove()
		else:
			image_cut.bl.set_button_image(self.bottom_left)

	def _create_button(self, row, column):
		button = Button(self, height=100, width=100)

		button['command'] = partial(self._cut_button_click, button)

		button.grid(row=row, column=column, sticky=W)
		button.grid_remove()

		return button

	def _cut_button_click(self, button):
		image_cut = button.image_cut

		if image_cut.one_width is True and image_cut.one_height is True:
			self.callback(image_cut.box[0], image_cut.box[1], self.key, self.index)
			self.top_right.grid_remove()
			self.top_left.grid_remove()
			self.bottom_right.grid_remove()
			self.bottom_left.grid_remove()
		else:
			self._set_buttons_from_cut(button.image_cut)


class ImageCut():
	def set_button_image(self, button):
		tk_image = ImageTk.PhotoImage(self.image)
		button['image'] = tk_image
		button.image = tk_image
		button.image_cut = self

	def __init__(self, image, box):
		self.tr = None
		self.tl = None
		self.br = None
		self.bl = None

		self.box = box
		self.one_width = self._box_is_one_or_zero_width(self.box)
		self.one_height = self._box_is_one_or_zero_height(self.box)

		self.original_image = image
		crop_box = (self.box[0], self.box[1], self.box[2], self.box[3])

		if crop_box[1] == crop_box[3]:
			crop_box = (crop_box[0], crop_box[1], crop_box[2], crop_box[3] + 1)

		if crop_box[0] == crop_box[2]:
			crop_box = (crop_box[0], crop_box[1], crop_box[2] + 1, crop_box[3])

		self.image = image.copy().crop(crop_box).resize((100, 100))

	def cut(self):
		boxes = self._split_boxes(self.box)

		if self.one_width is True and self.one_height is True:
			return

		if self.one_width is True:
			self.tr = ImageCut(self.original_image, boxes[0])
			self.br = ImageCut(self.original_image, boxes[2])
			pass
		elif self.one_height is True:
			self.tr = ImageCut(self.original_image, boxes[0])
			self.tl = ImageCut(self.original_image, boxes[1])
			pass
		else:
			self.tr = ImageCut(self.original_image, boxes[0])
			self.tl = ImageCut(self.original_image, boxes[1])
			self.br = ImageCut(self.original_image, boxes[2])
			self.bl = ImageCut(self.original_image, boxes[3])

	def _box_is_one_or_zero_width(self, box):
		return box[0] == box[2] or box[0] == box[2] - 1

	def _box_is_one_or_zero_height(self, box):
		return box[1] == box[3] or box[1] == box[3] - 1

	def _split_boxes(self, box):
		x_min = box[0]
		x_max = box[2]
		y_min = box[1]
		y_max = box[3]

		x_half = int((x_min + x_max) / 2)
		y_half = int((y_min + y_max) / 2)

		return [
			(x_min, y_min, x_half, y_half),
			(x_half, y_min, x_max, y_half),
			(x_min, y_half, x_half, y_max),
			(x_half, y_half, x_max, y_max)
		]
